﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TimeMachine.Engine
{
	public static class EnumerableExtensions
	{
		public static IEnumerable<KeyValuePair<int, T>> LogRepresentatives<T>(this IEnumerable<T> items)
		{
			var array = items.ToArray();
			if (array.Length == 0) yield break;
			for (var i = 1; i <= array.Length; i *= 2)
				yield return new KeyValuePair<int, T>(i, array[i-1]);
		}

		public static IEnumerable<T> SelectRepresentatives<T>(this IEnumerable<T> items, int maxCount)
		{
			if (!items.Any()) return new T[0];
			var arr = items.ToArray();
			var count = arr.Length;
			var resultCount = Math.Min(count, maxCount);
			var step = ((double) count - 1)/(resultCount - 1);
			return Enumerable.Range(0, resultCount).Select(i => arr[(int) (i*step)]
				);
		}

		public static string ToString<T>(this IEnumerable<T> items, string delimiter, Func<T, string> toString)
		{
			if (items.Any())
				return items.Skip(1).Aggregate(
					toString(items.First()),
					(s, item) => s + delimiter + toString(item)
					);
			return string.Empty;
		}

		public static int BinarySearch<T>(this IList<T> list, Func<T, int> whereToContinueSearch)
		{
			int left = 0;
			int right = list.Count - 1;
			while (left <= right)
			{
				int mid = left + ((right - left) >> 1);
				int c = whereToContinueSearch(list[mid]);
				if (c == 0) return mid;
				if (c > 0) left = mid + 1;
				else right = mid - 1;
			}
			return -1;
		}
	}
}